using System;
using System.Collections.Generic;
using Sce.Pss.Core.Graphics;
using Sce.Pss.HighLevel.Model;

namespace UTFramework
{
	public class Library
	{
		#region Variables
		private Dictionary<string,Item> _loadedItems;
		#endregion
		
		#region ctor
		
		private static Library _instance;

		public static Library Instance {
			get {
				if (_instance == null) {
					_instance = new Library ();
				}
				return _instance;
			}
		}
		
		private Library ()
		{
			_loadedItems = new Dictionary<string, Item> ();
		}
		
		#endregion
		
		#region Item Methods

		public Sprite GetSprite (string path)
		{
			Sprite sprite = (Sprite)CheckLibrary (path);
			
			if (sprite == null) {
				// if we don't have sprite
				Texture2D myTexture;
				myTexture = new Texture2D (path, false);
				myTexture.SetWrap (TextureWrapMode.ClampToEdge);
				sprite = new Sprite (myTexture, 10.0f, 20.0f);
				RegisterItem (sprite, path);	
			}
			return sprite;
		}
		
		public BasicModel GetModel (string path, int index =0)
		{
			BasicModel model = (BasicModel)CheckLibrary (path);
			if (model == null) {
				model = new BasicModel (path, index);
				RegisterItem (model, path);
			}
			return model;
		}
		
		public void ReleaseItem (string path)
		{
			if (!_loadedItems.ContainsKey (path)) {
				Console.WriteLine ("WARNING: Resource '{0}' already released or doesn't registred", path);
				return;
			}
			
			var res = _loadedItems [path];
			res.LinkCount -= 1;
			if (_loadedItems [path].LinkCount == 0) {
				if (_loadedItems [path].Resource is IDisposable) {
					((IDisposable)_loadedItems [path].Resource).Dispose ();
				}
								
				_loadedItems.Remove (path);
			}
		}
		
		#endregion
		
		#region Private Methods

		private void RegisterItem (object resource, string path)
		{
			Item item = new Item ();
			item.Resource = resource;
			item.LinkCount = 1;
			_loadedItems.Add (path, item);
		}

		private object CheckLibrary (string path)
		{
			if (_loadedItems.ContainsKey (path)) {
				var res = _loadedItems [path];
				res.LinkCount += 1;
				return _loadedItems [path].Resource;
			}
			
			return null;
		}
		#endregion
		
		#region implement of IDisposable
		
		public void Dispose ()
		{
			if (_loadedItems != null) {
				foreach (Item item in _loadedItems.Values) {
					if (item.Resource != null) {
						if (item.Resource is IDisposable) {
							((IDisposable)item.Resource).Dispose ();
						}
					}
						
				}
				_loadedItems.Clear ();
				_loadedItems = null;
			}
		}
		
		#endregion
	}
}

